var crypto = require('crypto');
var querystring = require('querystring');
var needle = require('needle');
var randomString = require('random-string');
var xml2js = require('xml2js');
var parseString = require('xml2js').parseString;
var PackageXmlMessage = require('./PackageXmlMessage');
var payUtil = require('./payUtil');
var wxpay = require('./wxpay.json');
var option = {
    headers:{
        'Content-Type':'text/xml'
    },
    decode:false
}

exports.getNotifyUrl = function(){
    return wxpay.notify_url;
}
exports.getNonceStr = function(len){
    return payUtil.generateNonce(len);
}
/**
 * jsapi 签名
 * @param url
 * @param jsapi_ticket
 * @returns {string}
 */
exports.jsapiSign = function(url, jsapi_ticket){
    var obj = {
        noncestr: payUtil.generateNonce(32),
        jsapi_ticket: jsapi_ticket,
        timestamp: payUtil.generateTimeStamp()+'',
        url: url
    }
    var tempObj = payUtil.ksort(obj);
    var str = payUtil.stringify(tempObj);
    var sign = payUtil.sha1(decodeURIComponent(str))
    return {
        appId: wxpay.appid,
        timestamp: obj.timestamp,
        nonceStr: obj.noncestr,
        signature: sign
    };
}

/**
 * 起调支付api参数
 * @param prepay_id
 * @returns {{appId: *, nonceStr: *, package: string, signType: string, timeStamp: number}}
 */
exports.requestJsPay = function(prepay_id){
    var obj = {
        appId: wxpay.appid,
        nonceStr: payUtil.generateNonce(32),
        package: 'prepay_id='+prepay_id,
        signType: 'MD5',
        timeStamp: payUtil.generateTimeStamp()+''
    }
    var tempObj = payUtil.ksort(obj);
        tempObj.key = wxpay.partner_key;
    var paySign = payUtil.md5(decodeURIComponent(payUtil.stringify(tempObj)));
        obj.paySign = paySign;
    return obj;
}
/**
 * 起调共享地址api参数
 * @param acctoken
 * @param url
 * @returns {{appId: *, scope: string, signType: string, addrSign: string, timeStamp: *, nonceStr: *}}
 */
exports.requestJsAddr = function(acctoken, url){
    var obj = {
        appid: wxpay.appid,
        timestamp: payUtil.generateTimeStamp(),
        noncestr: payUtil.generateNonce(32),
        accesstoken: acctoken,
        url: url
    }
    var tempObj = payUtil.ksort(obj);
    var addrSign = payUtil.sha1(decodeURIComponent(payUtil.stringify(tempObj))).toLowerCase();
    var params = {
        appId: wxpay.appid,
        scope: 'jsapi_address',
        signType: 'sha1',
        addrSign: addrSign,
        timeStamp: obj.timestamp,
        nonceStr: obj.noncestr
    }
    return params;
}

/**
 * get 微信支付 package
 * @param payInfo
 * @param callback
 */
exports.requestPackage = function(payInfo, callback){
    var packageXml = new PackageXmlMessage(payInfo);
    var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    needle.post(url, packageXml.toXMLString(), option, function(err, resp, body){
        if(err){
            return callback(err)
        }
        var packageObj = {};
        parseString(body, function(err, data){
            var xml = data.xml;
            if(xml.return_code){
                packageObj.return_code = xml.return_code[0];
            }
            if(xml.return_msg){
                packageObj.return_msg = xml.return_msg[0];
            }
            if(xml.appid){
                packageObj.appid = xml.appid[0];
            }
            if(xml.mch_id){
                packageObj.mch_id = xml.mch_id[0];
            }
            if(xml.nonce_str){
                packageObj.nonce_str = xml.nonce_str[0];
            }
            if(xml.sign){
                packageObj.sign = xml.sign[0];
            }
            if(xml.result_code){
                packageObj.result_code = xml.result_code[0];
            }
            if(xml.prepay_id){
                packageObj.prepay_id = xml.prepay_id[0];
            }
            if(xml.trade_type){
                packageObj.trade_type = xml.trade_type[0];
            }
            callback(null, packageObj)
        })
    });
}
/**
 * 处理返回通知
 * @param notify_xml
 * @param callback
 */
exports.handleNotify = function(req, res, callback){
    var _self = this;
    var buf = '';
    req.setEncoding('utf8');
    req.on('data', function(chunk){
        buf += chunk;
    });
    req.on('end', function(){
        _self.handleNotifyMsg(buf, function(err, msg){
            callback(err, msg);
        })
    });
}
/**
 * 获得反馈消息
 * @param returnCode SUCCESS FAIL
 * @param returnMsg ''
 * @returns {string}
 */
exports.getNotifyResponseXml = function(returnCode, returnMsg){
    return '<xml>\
                <return_code><![CDATA['+returnCode+']]></return_code>\
                <return_msg><![CDATA['+returnMsg+']]></return_msg>\
            </xml>';
}

exports.handleNotifyMsg = function(notify_xml, callback){
    parseString(notify_xml, function(err, data){
        if(err) return callback(err);
        var xml = data.xml;
        var notify = {};
        if(xml.return_code){
            notify.return_code = xml.return_code[0];
        }
        if(xml.return_msg){
            notify.return_msg = xml.return_msg[0];
        }
        if(xml.appid){
            notify.appid = xml.appid[0];
        }
        if(xml.mch_id){
            notify.mch_id = xml.mch_id[0];
        }
        if(xml.device_info){
            notify.device_info = xml.device_info[0];
        }
        if(xml.nonce_str){
            notify.nonce_str = xml.nonce_str[0];
        }
        if(xml.sign){
            notify.sign = xml.sign[0];
        }
        if(xml.return_code){
            notify.return_code = xml.return_code[0];
        }
        if(xml.openid){
            notify.openid = xml.openid[0];
        }
        if(xml.is_subscribe){
            notify.is_subscribe = xml.is_subscribe[0];
        }
        if(xml.trade_type){
            notify.trade_type = xml.trade_type[0];
        }
        if(xml.bank_type){
            notify.bank_type = xml.bank_type[0];
        }
        if(xml.total_fee){
            notify.total_fee = xml.total_fee[0];
        }
        if(xml.coupon_fee){
            notify.coupon_fee = xml.coupon_fee[0];
        }
        if(xml.fee_type){
            notify.fee_type = xml.fee_type[0];
        }
        if(xml.transaction_id){
            notify.transaction_id = xml.transaction_id[0];
        }
        if(xml.out_trade_no){
            notify.out_trade_no = xml.out_trade_no[0];
        }
        if(xml.attach){
            notify.attach = xml.attach[0];
        }
        if(xml.time_end){
            notify.time_end = xml.time_end[0];
        }
        if(xml.err_code){
            notify.err_code = xml.err_code[0];
        }
        if(xml.err_code_des){
            notify.err_code_des = xml.err_code_des[0];
        }
        callback(null, notify);
    })
}

